<!-- 消息弹窗，交互dom -->
<script setup>
// #导出vue方法
import {
	// 获取组件实例对象
	getCurrentInstance,
	// 钩子-卸载前
	onBeforeUnmount,
	// 钩子-组件挂载完成后执行
	onMounted,
	ref,
} from "vue";

// -------------------------------------------------------------------

const props = defineProps({
	// id
	uid: {
		type: Number,
		default: null,
	},

	// 创建位置
	offsetTop: {
		type: Number,
		default: 45,
	},

	// 消息文本
	message: {
		type: String,
		default: "",
	},

	// 弹窗自动关闭时间，默认2s超时，单位秒
	timeClose: {
		type: Number,
		default: 2,
	},

	// 显示层级
	zIndex: {
		type: String,
		default: "",
	},

	// 消息类型 success 成功  warning 警告 error 错误 default 默认
	type: {
		type: String,
		default: "default",
	},

	// 关闭时的回调函数
	onClose: {
		type: Function,
		default: () => {},
	},
});

// 组件实例
const instance = getCurrentInstance();
// 页面显示
const viewShow = ref(false);
// 关闭计时器
const closeTimer = ref(null);

onMounted(() => {
	// 挂载完成，触发
	clearTimeout(closeTimer.value);

	viewShow.value = true;
	closeTimer.value = setTimeout(() => {
		onMessageClose();
	}, props.timeClose * 1000);
});

onBeforeUnmount(() => {
	// 清理计时器
	clearTimeout(closeTimer.value);
});

// 主动关闭界面
const onMessageClose = () => {
	viewShow.value = false;
	clearTimeout(closeTimer.value);

	// 触发关闭方法，通知上级
	props.onClose(props.uid);
};

// 组件卸载后处理
const onHandleAfterLeave = () => {
	// 卸载后清理实例
	if (instance) {
		instance.proxy.$el.remove();
	}
};
</script>

<template>
	<transition name="message" @after-leave="onHandleAfterLeave">
		<div
			v-show="viewShow"
			class="message"
			:class="type"
			:style="`top: ${offsetTop}px; z-index: ${zIndex}`"
		>
			<!-- 图标 -->
			<div class="icon"></div>

			<!-- 警告文本 -->
			<div class="text">
				{{ message }}
			</div>

			<!-- 关闭按钮 -->
			<div class="close" @click.stop="onMessageClose"></div>
		</div>
	</transition>
</template>

<style lang="less" scoped>
.message {
	position: fixed;
	top: 45px;
	left: 50%;
	display: flex;
	align-items: center;
	width: 564px;
	height: 75px;
	color: #909399;
	background-color: #edf2fc;
	border: 2px solid #edf2fc;
	border-radius: 6px;
	transform: translate(-50%, 0);
	transition: top 0.2s;

	.icon {
		display: flex;
		align-items: center;
		justify-content: center;
		width: 68px;
		height: 100%;

		i {
			font-size: 24px;
		}
	}

	.text {
		flex: 1;
		font-size: 24px;
		font-weight: 500;
	}

	.close {
		display: flex;
		align-items: center;
		justify-content: center;
		width: 68px;
		height: 100%;
	}
	.close i {
		font-size: 28px;
	}
}

.success {
	color: rgba(103, 194, 57, 1);
	background-color: rgba(240, 249, 234, 1);
	border-color: rgba(225, 242, 216, 1);
}
.warning {
	color: rgba(230, 162, 60, 1);
	background-color: rgba(253, 246, 235, 1);
	border-color: rgba(250, 236, 216, 1);
}
.error {
	color: rgba(245, 108, 108, 1);
	background-color: rgba(254, 240, 240, 1);
	border-color: rgba(253, 226, 226, 1);
}

/* 动画 */
.message-enter-active,
.message-leave-active {
	transition: opacity 0.2s, transform 0.2s;
}

.message-enter-from,
.message-leave-to {
	opacity: 0;
	transform: translate(-50%, -100%);
}

.message-enter-to {
	opacity: 1;
	transform: translate(-50%, 0);
}
</style>
